﻿// first_libevent.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include<event2/event.h>
#include <iostream>
#include<signal.h>
#include<event2/listener.h>
#include<event2//bufferevent.h>
#include"XThreadPool.h"
#include"XFtpServerCMD.h"
using namespace std;
#include<string.h>
void ReadCB(struct bufferevent* bev, void* ctx){
    cout << "+" << flush;
    char buf[1024] = { 0 };
    int len = bufferevent_read(bev, buf, 1024-1);
    cout << buf << endl;
    bufferevent_write(bev, "OK", 3);
}
void WriteCB(struct bufferevent* bev, void* ctx) {
    cout << "w" << endl;
}
void EventCB(struct bufferevent* bev, short what, void* ctx) {
    cout << "E" << endl;
    if (what & BEV_EVENT_TIMEOUT&&what&BEV_EVENT_READING) {
        cout << "BEV_EVENT_TIMEOUT BEV_EVENT_READING" << endl;

        bufferevent_free(bev);
    }
    else if (what & BEV_EVENT_TIMEOUT && what & BEV_EVENT_WRITING) {
        cout << "BEV_EVENT_TIMEOUT BEV_EVENT_WRITING" << endl;

        bufferevent_free(bev);
    }
    else if (what & BEV_EVENT_ERROR) {
        cout << "BEV_EVENT_ERROR " << endl;
        bufferevent_free(bev);
    }
    else if (what & BEV_EVENT_EOF) {
        cout << "BEV_EVENT_EOF " << endl;
        bufferevent_free(bev);
    }
}
void ListenCB(struct evconnlistener* evc, evutil_socket_t client_socket, struct sockaddr* client_addr, int socklen, void* arg)
{
    XFtpServerCMD* task = new XFtpServerCMD();
    task->sock = client_socket;
    XThreadPool::Get()->dispatch(task);
}
int main()
{
#ifdef _WIN32
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2),&wsa);
#else
    if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
        return 1;
#endif
    std::cout << "Hello World!\n";
    XThreadPool::Get()->Init(10);
    event_base *base= event_base_new();
    if (base) {
        std::cout << "ok" << std::endl;
    }
   
    sockaddr_in sin;
    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    int server_port = 8080;
    sin.sin_port = htons(server_port);
    auto evc=evconnlistener_new_bind(base,ListenCB,base,LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE,10,
        (sockaddr*)&sin,sizeof(sin));
    cout << "bind port success"<<server_port<<endl;

    event_base_dispatch(base);
    evconnlistener_free(evc);
    event_base_free(base);
    return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
